/*
 * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.lang;
import java.util.Random;

import sun.misc.FloatConsts;
import sun.misc.DoubleConsts;

/**
 * {@code Math}类包含用于执行基本数学运算的方法, 比如基本指数、对数、平方根和三角函数等.
 *
 * <p>和{@code StrictMath}类中的某些数学方法不同,
 * 所有{@code Math}类中的等价函数的实现都没有定义为返回逐位相同的结果.
 * 此类在不需要严格重复的地方可以得到更好的执行.
 *
 * <p>默认情况下,许多{@code Math}中的方法都只是简单的调用{@code StrictMath}中的等价方法来作为默认实现.
 * 建议代码生成器使用特定于平台的本地库或者微处理器指令(如果可以的话)来提供{@code Math}方法更高性能的实现.
 * 这种更高性能的实现仍然必须遵守{@code Math}的规范.
 *
 * <p>实现规范的质量涉及到两种属性, 即返回结果的准确性和方法的单调性.
 * 事实上,浮点{@code Math}方法的准确性是通过根据<i>ulps</i>(units in the last place,最后一位的进退位)来衡量的.
 * 对于一个给定的浮点数格式, 特定实数值的{@linkplain #ulp(double) ulp}是包括该数值的两个浮点值的差.
 * 当作为一个整体而不是针对具体参数讨论方法的准确性时, 引入的ulp数用于任何参数最差情况下的误差.
 * 如果一个方法的误差总是小于 0.5 ulp, 那么该方法始终返回最接近准确结果的浮点数;这种方法就是<i>正确舍入</i>.
 * 一个正确舍入的方法通常能得到最佳的浮点近似值; 然而, 对于许多浮点方法, 进行正确舍入是不太现实的.
 * 相反, 对于{@code Math}类, 有些方法允许更大一点(1或2ulps内)的误差.
 * 非正式地, 对于 1 ulp 的误差范围, 当准确结果是可表示的数值时, 应该按照计算结果返回准确结果;
 * 否则,返回包括准确结果的两个浮点值中的一个.
 * 对于量级很大的准确结果,结果可以是无穷大.
 * 除了个别参数的准确性之外,维护不同参数的方法之间的正确关系也很重要.
 * 因此,大多数误差大于0.5 ulp的方法都要求是<i>半单调的</i>:
 * 只要数学函数是非递减的, 浮点近似值就是非递减的;
 * 同样, 只要数学函数是非递增的, 浮点近似值就是非递增的.
 * 并非所有准确性为 1 ulp 的近似值都能自动满足单调性要求.
 *
 * <p>
 * Java平台采用有符号的二进制补码来对基本类型int和long进行整数计算.
 * 开发者应当采用基本类型来保证计算操作始终能产生正确的结果,
 * 这意味着在一些情况下,这些计算操作并不会溢出该数据类型的范围.
 * 最好的使用方法是采用基本类型及算法来避免溢出.
 * 在一些情况下,{@code int}或{@code long}溢出需要被捕获到,
 * 那么可以采用{@code addExact}, {@code subtractExact},{@code multiplyExact}以及{@code toIntExact}方法,
 * 当计算结果溢出时,它们会抛出一个{@code ArithmeticException}.
 * 对于其它的算术操作,比如除法,绝对值运算,自增,自减,以及取反,只有当结果为最大或者最小值时才会出现溢出,
 * 应当酌情进行检查以避免最大或最小值.
 *
 * @author  unascribed
 * @author  Joseph D. Darcy
 * @since   JDK1.0
 */

public final class Math {

    /**
     * 不允许实例化该类.
     */
    private Math() {}

    /**
     * 最接近　<i>e</i>　的{@code double}值, 基于自然对数.
     */
    public static final double E = 2.7182818284590452354;

    /**
     * 最接近　<i>pi</i>　的{@code double}值, 即圆的周长与直径之比.
     */
    public static final double PI = 3.14159265358979323846;

    /**
     * 返回角的三角正弦.
     * 特殊情况如下:
     * <ul><li>如果参数为NaN或无穷大, 那么返回结果为NaN.
     * <li>如果参数为0, 那么返回结果为0, 符号与参数符号相同.
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   a   以弧度表示的角.
     * @return  参数的正弦.
     */
    public static double sin(double a) {
        return StrictMath.sin(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回角的三角余弦.
     * 特殊情况如下:
     * <ul>
     *     <li>如果参数为NaN或无穷大, 那么返回结果为NaN.
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   a   以弧度表示的角.
     * @return  参数的余弦.
     */
    public static double cos(double a) {
        return StrictMath.cos(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回角的三角正切.
     * 特殊情况如下:
     * <ul>
     *     <li>如果参数为NaN或无穷大, 那么返回结果为NaN.
     *     <li>如果参数为0, 那么返回结果为0, 符号与参数符号相同.
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   a   以弧度表示的角.
     * @return  参数的正切.
     */
    public static double tan(double a) {
        return StrictMath.tan(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回一个值的反正弦; 返回的角度在-<i>pi</i>/2 到 <i>pi</i>/2 之间.
     * 特殊情况如下:
     * <ul><li>如果参数为NaN或者它的绝对值大于1, 那么结果为NaN.
     * <li>如果参数为0, 那么返回结果为0, 符号与参数符号相同.
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   a   要返回反正弦的值.
     * @return  参数的反正弦.
     */
    public static double asin(double a) {
        return StrictMath.asin(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回一个值的反余弦; 返回的角度范围在 0.0 到 <i>pi</i> 之间.
     * 特殊情况如下:
     * <ul>
     *     <li>如果参数为NaN或者它的绝对值大于1, 那么结果为NaN.
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   a  要返回反余弦的值.
     * @return  参数的反正弦.
     */
    public static double acos(double a) {
        return StrictMath.acos(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回一个值的反正切; 返回的角度范围在  -<i>pi</i>/2 到 <i>pi</i>/2 之间.
     * 特殊情况如下：
     * <ul>
     *     <li>如果参数为NaN, 那么结果为NaN.
     *     <li>如果参数为0, 那么返回结果为0, 符号与参数符号相同.
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   a   要返回反正切的值.
     * @return  参数的反正切.
     */
    public static double atan(double a) {
        return StrictMath.atan(a); // default impl. delegates to StrictMath
    }

    /**
     * 将一个用角度表示的角转换为近似相等的用弧度表示的角.
     * 从角度到弧度的转换通常情况下是不精确的.
     *
     * @param   angdeg   度数表示的角.
     * @return  角  {@code angdeg} 用弧度表示的值.
     * @since   1.2
     */
    public static double toRadians(double angdeg) {
        return angdeg / 180.0 * PI;
    }

    /**
     * 将一个用弧度表示的角转换为近似相等的用角度表示的角.
     * 从弧度到角度的转换通常情况下是不精确的;
     * 用户<i>不</i>应该期望{@code cos(toRadians(90.0))}和{@code 0.0}完全相等.
     *
     * @param   angrad   用弧度表示的角
     * @return  角  {@code angrad} 用角度表示的值.
     * @since   1.2
     */
    public static double toDegrees(double angrad) {
        return angrad * 180.0 / PI;
    }

    /**
     * 返回欧拉数<i>e</i>的{@code double}次幂的值.
     * 特殊情况如下:
     * <ul>
     *     <li>如果参数为NaN, 结果为NaN.
     *     <li>如果参数为正无穷, 那么结果为正无穷.
     *     <li>如果参数为负无穷, 那么结果为正0.
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   a   <i>e</i>的指数.
     * @return  <i>e</i><sup>{@code a}</sup>的值,
     *          其中<i>e</i>是自然对数的底数.
     */
    public static double exp(double a) {
        return StrictMath.exp(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回一个{@code double}值的自然对数(底数是<i>e</i>).
     * 特殊情况如下:
     * <ul>
     *     <li>如果参数为NaN或者小于0,那么返回结果为NaN.
     *     <li>如果参数为正无穷, 那么返回结果为正无穷.
     *     <li>如果参数为正0或负0, 那么返回结果为负无穷.
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   a 一个值
     * @return  ln&nbsp;{@code a}的值, 即 {@code a}的自然对数.
     */
    public static double log(double a) {
        return StrictMath.log(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回{@code double}值的底数为10的对数.
     * 特殊情况如下:
     *
     * <ul><li>如果参数为NaN或者小于0, 那么结果为NaN.
     * <li>如果参数为正无穷, 那么结果为正无穷.
     * <li>如果参数是正0或者负0, 那么返回结果为负无穷.
     * <li> 如果参数等于10<sup><i>n</i></sup>(n为整数),那么结果为<i>n</i>.
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   a 一个值
     * @return  {@code a}的底数为10的对数.
     * @since 1.5
     */
    public static double log10(double a) {
        return StrictMath.log10(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回正确舍入的 {@code double} 值的正平方根
     * 特殊情况如下:
     * <ul><li>如果参数为NaN或者小于0, 结果为NaN.
     * <li>如果参数为正无穷, 那么结果为正无穷.
     * <li>如果参数是正0或者负0,那么结果与参数相同.
     * </ul>
     * 否则, 结果为最接近该参数值的实际数学平方根的{@code double}值.
     *
     * @param   a 一个值.
     * @return  {@code a}的正平方根.
     *          如果参数为NaN或者小于0, 结果为NaN.
     */
    public static double sqrt(double a) {
        return StrictMath.sqrt(a); // default impl. delegates to StrictMath
                                   // Note that hardware sqrt instructions
                                   // frequently can be directly used by JITs
                                   // and should be much faster than doing
                                   // Math.sqrt in software.
    }


    /**
     * 返回{@code double}值的立方根 value.
     * 对于正的有限数{@code x}, {@code cbrt(-x) == -cbrt(x)};
     * 也就是说, 负值的立方根是该值数值的负立方根.
     *
     * 特殊情况如下:
     *
     * <ul>
     *
     * <li>如果参数为NaN, 那么结果为NaN.
     *
     * <li>如果参数是无穷的, 符号同参数的符号相同.
     *
     * <li>如果参数为0, 那么结果为0,符号同参数的符号相同.
     *
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     *
     * @param   a  一个值.
     * @return  {@code a}的立方根.
     * @since 1.5
     */
    public static double cbrt(double a) {
        return StrictMath.cbrt(a);
    }

    /**
     * 按照 IEEE 754 标准的规定,对两个参数进行取余运算.
     * 余数的算术值等于<code>f1&nbsp;-&nbsp;f2</code>&nbsp;&times;&nbsp;<i>n</i>,
     * 其中<i>n</i>是最接近商{@code f1/f2}准确算术值的整数,
     * 如果两个整数都同样的接近{@code f1/f2},那么<i>n</i>是其中的偶数.
     * 如果余数为0,那么它的符号与第一个参数的符号相同.
     * 特殊情况如下:
     * <ul>
     *     <li>如果任意一个参数为NaN,或者第一个参数为无穷大,或者第二个参数为正0或者负0,那么结果为NaN.
     *     <li>如果第一个参数是有限的,并且第二个参数是无穷大的,那么结果和第一个参数相同.
     * </ul>
     *
     * @param   f1   被除数.
     * @param   f2   除数.
     * @return  {@code f1}除以{@code f2}的余数.
     */
    public static double IEEEremainder(double f1, double f2) {
        return StrictMath.IEEEremainder(f1, f2); // delegate to StrictMath
    }

    /**
     * 返回最小的(最接近负无穷大){@code double}值, 该值大于等于参数,并且等于某个整数.
     * 特殊情况如下:
     * <ul>
     *     <li>如果参数值已经等于某个整数, 那么结果与该参数相同.
     *     <li>如果参数为NaN或无穷大或者正0或者负0,那么结果与该参数相同.
     *     <li>如果参数小于0但是大于 -1.0,那么结果为负0.
     * </ul>
     * 需要注意的是,{@code Math.ceil(x)}的值与{@code -Math.floor(-x)}的值完全相同.
     *
     * @param   a  一个值.
     * @return  最小的(最接近负无穷大)浮点值,该值大于等于该参数,并等于某个整数.
     */
    public static double ceil(double a) {
        return StrictMath.ceil(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回最大的(最接近正无穷)的{@code double}值,该值小于等于该参数, 并等于某个整数.
     * 特殊情况如下:
     * <ul>
     *     <li>如果参数已经等于某个整数,那么结果和该参数相同.
     *     <li>如果参数为NaN或无穷大或者正0或者负0,那么结果和该参数相同.
     * </ul>
     *
     * @param   a  一个值.
     * @return  最大(最接近正无穷大)浮点值, 该值小于等于该参数, 并等于某个整数.
     */
    public static double floor(double a) {
        return StrictMath.floor(a); // default impl. delegates to StrictMath
    }

    /**
     * 返回最接近参数的{@code double}值,该值等于某个整数.
     * 如果两个同为整数的{@code double}值都同样接近,那么结果取偶数.
     * 特殊情况如下:
     * <ul>
     *     <li>如果参数已经等于某个整数,那么结果和该参数相同.
     *     <li>如果参数为NaN或无穷大或者正0或者负0,那么结果和该参数相同.
     * </ul>
     *
     * @param   a  {@code double}值.
     * @return  最接近 {@code a}的整数浮点值.
     */
    public static double rint(double a) {
        return StrictMath.rint(a); // default impl. delegates to StrictMath
    }

    /**
     * 将矩形坐标 ({@code x},&nbsp;{@code y}) 转换成极坐标 (r,&nbsp;<i>theta</i>), 返回所得角<i>theta</i>.
     * 该方法通过计算  {@code y/x} 的反正切值来计算相角 <i>theta</i>, 范围为从 -<i>pi</i> 到 <i>pi</i>.
     * 特殊情况如下:
     * <ul><li>如果任意一个参数为NaN, 那么结果为NaN.
     * <li>如果第一个参数为正0, 并且第二个参数为正数;或者第一个参数为正的有限值, 并且第二个参数为正无穷大,
     * 那么结果为正0.
     * <li>如果第一个参数为负0, 并且第二个参数为正数;或者第一个参数为负的有限值, 并且第二个参数为正无穷大,
     * 那么结果为负0.
     * <li>如果第一个参数为正0, 并且第二个参数为负数;或者第一个参数为正的有限值, 并且第二个参数为负无穷大,
     * 那么结果为最接近<i>pi</i>的{@code double}值.
     * <li>如果第一个参数为负0, 并且第二个参数为负数;或者第一个参数为负的有限值, 并且第二个参数为负无穷大,
     * 那么结果为最接近-<i>pi</i>的{@code double}值.
     * <li>如果第一个参数为正数, 并且第二个参数为正0或负0;或者第一个参数为正无穷大, 第二个参数为有限值, 
     * 那么结果为最接近 <i>pi</i>/2的 {@code double} 值.
     * <li>如果第一个参数为负数, 并且第二个参数为正0或负0;或者第一个参数为负无穷大, 第二个参数为有限值, 
     * 那么结果为最接近 <i>pi</i>/2的 {@code double} 值.
     * <li>如果两个参数都为正无穷大, 那么结果为最接近 <i>pi</i>/4的 {@code double} 值.
     * <li>如果第一个参数为正无穷大, 第二个参数为负无穷大, 那么结果为最接近 3*<i>pi</i>/4 的 {@code double} 值.
     * <li>如果第一个参数为负无穷大, 第二个参数为正无穷大, 那么结果为最接近 -<i>pi</i>/4 的 {@code double} 值
     * <li>如果两个参数都为负无穷大, 那么结果为最接近 -3*<i>pi</i>/4 的 {@code double} 值.
     *
     * <p>计算结果必须在准确结果的 2 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   y   纵坐标
     * @param   x   横坐标
     * @return  与笛卡儿坐标中点 (<i>x</i>,&nbsp;<i>y</i>)对应的
     *          极坐标中点  (<i>r</i>,&nbsp;<i>theta</i>) 的 (<i>r</i>,&nbsp;<i>theta</i>) 组件.
     */
    public static double atan2(double y, double x) {
        return StrictMath.atan2(y, x); // default impl. delegates to StrictMath
    }

    /**
     * 返回第一个参数的第二个参数次幂的值.
     * 特殊情况如下:
     *
     * <ul><li>第二个参数为正 0 或负 0, 那么结果为1.0
     * <li>如果第二个参数为1.0, 那么结果同第一个参数相同.
     * <li>如果第二个参数为NaN, 那么结果为NaN.
     * <li>如果第一个参数为NaN并且第二个参数为非0值,那么结果为NaN.
     *
     * <li>如果
     * <ul>
     * <li>第一个参数的绝对值大于1,并且第二个参数为正无穷,或者
     * <li>第一个参数的绝对值小于1,并且第二个参数为负无穷,
     * </ul>
     * 那么结果为正无穷.
     *
     * <li>如果
     * <ul>
     * <li>第一个参数的绝对值大于 1, 并且第二个参数为负无穷,或者
     * <li>第一个参数的绝对值小于 1, 并且第二个参数为正无穷,
     * </ul>
     * 那么结果为正0.
     *
     * <li>如果第一个参数的绝对值等于1并且第二个参数为无穷大, 那么结果为NaN.
     *
     * <li>如果
     * <ul>
     * <li>如果第一个参数为正0,并且第二个参数大于0,或者
     * <li>第二个参数为正无穷,并且第二个参数小于0,
     * </ul>
     * 那么结果为正0.
     *
     * <li>如果
     * <ul>
     * <li>如果第一个参数为正0,并且第二个参数小于0,或者
     * <li>第二个参数为正无穷, 并且第二个参数大于0,
     * </ul>
     * 那么结果为正无穷.
     *
     * <li>如果
     * <ul>
     * <li>如果第一个参数为负0, 并且第二个参数大于0但不是一个有限的奇整数,或者
     * <li>第一个参数为负无穷, 并且第二个参数小于零但不是一个有限的奇整数,
     * </ul>
     * 那么结果为正0.
     *
     * <li>如果
     * <ul>
     * <li>如果第一个参数为负0,并且第二个参数为正的有限奇整数,或者
     * <li>第一个参数为负无穷,并且第二个参数为负的有限奇整数
     * </ul>
     * 那么结果为负0.
     *
     * <li>如果
     * <ul>
     * <li>如果第一个参数为负0并且第二个参数小于0但不是一个有限的奇整数,或者
     * <li>第一个参数为负无穷并且第二个参数大于0但不是一个有限的奇整数,
     * </ul>
     * 那么结果为正无穷.
     *
     * <li>如果
     * <ul>
     * <li>如果第一个参数为负0并且第二个参数为负的有限奇整数,或者
     * <li>第一个参数为负无穷并且第二个参数为正的有限奇整数
     * </ul>
     * 那么结果为负无穷.
     *
     * <li>如果第一个参数为小于0的有限值,
     * <ul>
     * <li> 如果第二个参数为有限的偶数整数, 那么结果等于第一个参数绝对值的第二个参数次幂的结果.
     *
     * <li> 如果第二个参数为有限的奇数整数, 那么结果等于负的第一个参数绝对值的第二个参数次幂的结果.
     *
     * <li> 如果第二个参数为有限的非整数值, 结果为NaN.
     *
     * </ul>
     *
     * <li>如果参数均为整数, 并且结果恰好可以表示为一个{@code double}值,
     * 那么该结果恰好等于第一个参数的第二个参数次幂的算术结果.
     * </ul>
     *
     * <p>(在前面的描述中, 当且仅当浮点数为有限值并且是方法 {@link #ceil ceil} 的定点数, 
     * 或者是方法 {@link #floor floor} 的定点数时, 才可以认为浮点值是整数.
     * 当且仅当将某个单参数方法应用到某个值的结果等于该值时, 该值才是这个方法的定点值.)
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   a   基数.
     * @param   b   指数.
     * @return  {@code a}<sup>{@code b}</sup>的值.
     */
    public static double pow(double a, double b) {
        return StrictMath.pow(a, b); // default impl. delegates to StrictMath
    }

    /**
     * 返回最接近参数的{@code int}值,和四舍五入到正无穷有关系(译者注:原文为with ties rounding to positive infinity,这一句在这里很让人困惑).
     *
     * <p>
     * 特殊情况如下:
     * <ul><li>如果参数为NaN, the result is 0.
     * <li>如果参数为负无穷或者任何一个小于等于{@code Integer.MIN_VALUE}的值,那么返回{@code Integer.MIN_VALUE}.
     * <li>如果参数为正无穷或者任何一个大于等于{@code Integer.MAX_VALUE}的值,那么返回{@code Integer.MAX_VALUE}.
     * </ul>
     *
     * @param   a   需要四舍五入成{@code int}的浮点数
     * @return  四舍五入的最接近参数的{@code int}值
     * @see     java.lang.Integer#MAX_VALUE
     * @see     java.lang.Integer#MIN_VALUE
     */
    public static int round(float a) {
        int intBits = Float.floatToRawIntBits(a);
        int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK)
                >> (FloatConsts.SIGNIFICAND_WIDTH - 1);
        int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2
                + FloatConsts.EXP_BIAS) - biasedExp;
        if ((shift & -32) == 0) { // shift >= 0 && shift < 32
            // a is a finite number such that pow(2,-32) <= ulp(a) < 1
            int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK)
                    | (FloatConsts.SIGNIF_BIT_MASK + 1));
            if (intBits < 0) {
                r = -r;
            }
            // In the comments below each Java expression evaluates to the value
            // the corresponding mathematical expression:
            // (r) evaluates to a / ulp(a)
            // (r >> shift) evaluates to floor(a * 2)
            // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
            // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
            return ((r >> shift) + 1) >> 1;
        } else {
            // a is either
            // - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2
            // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
            // - an infinity or NaN
            return (int) a;
        }
    }

    /**
     * 返回最接近参数的{@code long}值,和四舍五入到正无穷有关系(译者注:原文为with ties rounding to positive infinity,这一句在这里很让人困惑).
     *
     * <p>特殊情况如下:
     * <ul><li>如果参数为NaN,那么结果为 0.
     * <li>如果参数为负无穷或者任何小于等于{@code Long.MIN_VALUE}的值,那么结果为{@code Long.MIN_VALUE}.
     * <li>如果参数为正无穷或者任何小于等于{@code Long.MAX_VALUE}的值,那么结果为{@code Long.MAX_VALUE}.
     * </ul>
     *
     * @param   a   需要四舍五入成{@code long}的浮点数
     * @return  四舍五入的最接近参数的{@code long}值
     * @see     java.lang.Long#MAX_VALUE
     * @see     java.lang.Long#MIN_VALUE
     */
    public static long round(double a) {
        long longBits = Double.doubleToRawLongBits(a);
        long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK)
                >> (DoubleConsts.SIGNIFICAND_WIDTH - 1);
        long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2
                + DoubleConsts.EXP_BIAS) - biasedExp;
        if ((shift & -64) == 0) { // shift >= 0 && shift < 64
            // a is a finite number such that pow(2,-64) <= ulp(a) < 1
            long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK)
                    | (DoubleConsts.SIGNIF_BIT_MASK + 1));
            if (longBits < 0) {
                r = -r;
            }
            // In the comments below each Java expression evaluates to the value
            // the corresponding mathematical expression:
            // (r) evaluates to a / ulp(a)
            // (r >> shift) evaluates to floor(a * 2)
            // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2)
            // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2)
            return ((r >> shift) + 1) >> 1;
        } else {
            // a is either
            // - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2
            // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer
            // - an infinity or NaN
            return (long) a;
        }
    }

    private static final class RandomNumberGeneratorHolder {
        static final Random randomNumberGenerator = new Random();
    }

    /**
     * 返回一个大于等于{@code 0.0}且小于{@code 1.0}的{@code double}值.
     * 返回值是一个伪随机选择的数,在该范围内(近似)均匀分布.
     *
     * <p>第一次调用该方法时,它将创建一个新的伪随机数生成器, 与以下表达式完全相同:
     *
     * <blockquote>{@code new java.util.Random()}</blockquote>
     *
     * 之后, 新的伪随机数生成器可用于此方法的所有调用, 但不能用于其他地方.
     *
     * <p>此方法是完全同步的, 可允许多个线程使用而不出现错误.
     * 然而,如果多个线程需要以极高的速率生成伪随机数,那么这可能会减少每个线程对拥有自己伪随机数生成器的占用.
     *
     * @return  大于等于{@code 0.0}且小于{@code 1.0}的伪随机{@code double}值.
     * @see Random#nextDouble()
     */
    public static double random() {
        return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
    }

    /**
     * 返回其参数的和,如果结果超出了{@code int}的范围,则会抛出一个异常.
     *
     * @param x 第一个值
     * @param y 第二个值
     * @return 计算结果
     * @throws ArithmeticException 如果结果超出了int的范围
     * @since 1.8
     */
    public static int addExact(int x, int y) {
        int r = x + y;
        // HD 2-12 Overflow iff both arguments have the opposite sign of the result
        if (((x ^ r) & (y ^ r)) < 0) {
            throw new ArithmeticException("integer overflow");
        }
        return r;
    }

    /**
     * 返回其参数的和,如果结果超出了{@code long}的范围,则会抛出一个异常.
     *
     * @param x 第一个值
     * @param y 第二个值
     * @return 计算结果
     * @throws ArithmeticException 如果结果超出了long的范围
     * @since 1.8
     */
    public static long addExact(long x, long y) {
        long r = x + y;
        // HD 2-12 Overflow iff both arguments have the opposite sign of the result
        if (((x ^ r) & (y ^ r)) < 0) {
            throw new ArithmeticException("long overflow");
        }
        return r;
    }

    /**
     * 返回两个参数之差,如果结果超出了{@code int}的范围,则会抛出一个异常.
     *
     * @param x 第一个值
     * @param y 要从第一个值里面减去的第二个的值
     * @return 计算结果
     * @throws ArithmeticException 如果结果超出了int的范围
     * @since 1.8
     */
    public static int subtractExact(int x, int y) {
        int r = x - y;
        // HD 2-12 Overflow iff the arguments have different signs and
        // the sign of the result is different than the sign of x
        if (((x ^ y) & (x ^ r)) < 0) {
            throw new ArithmeticException("integer overflow");
        }
        return r;
    }

    /**
     * 返回两个参数之差,如果结果超出了{@code long}的范围,则会抛出一个异常.
     *
     * @param x 第一个值
     * @param y 要从第一个值里面减去的第二个的值
     * @return 计算结果
     * @throws ArithmeticException 如果结果超出了long的范围
     * @since 1.8
     */
    public static long subtractExact(long x, long y) {
        long r = x - y;
        // HD 2-12 Overflow iff the arguments have different signs and
        // the sign of the result is different than the sign of x
        if (((x ^ y) & (x ^ r)) < 0) {
            throw new ArithmeticException("long overflow");
        }
        return r;
    }

    /**
     * 返回两个参数的乘积,如果结果超出了{@code int}的范围,则会抛出一个异常.
     *
     * @param x 第一个值
     * @param y 第二个值
     * @return 计算结果
     * @throws ArithmeticException 如果结果超出了int的范围
     * @since 1.8
     */
    public static int multiplyExact(int x, int y) {
        long r = (long)x * (long)y;
        if ((int)r != r) {
            throw new ArithmeticException("integer overflow");
        }
        return (int)r;
    }

    /**
     * 返回两个参数的乘积,如果结果超出了{@code long}的范围,则会抛出一个异常.
     *
     * @param x 第一个值
     * @param y 第二个值
     * @return 计算结果
     * @throws ArithmeticException 如果结果超出了long的范围
     * @since 1.8
     */
    public static long multiplyExact(long x, long y) {
        long r = x * y;
        long ax = Math.abs(x);
        long ay = Math.abs(y);
        if (((ax | ay) >>> 31 != 0)) {
            // Some bits greater than 2^31 that might cause overflow
            // Check the result using the divide operator
            // and check for the special case of Long.MIN_VALUE * -1
           if (((y != 0) && (r / y != x)) ||
               (x == Long.MIN_VALUE && y == -1)) {
                throw new ArithmeticException("long overflow");
            }
        }
        return r;
    }

    /**
     * 返回参数加一后的结果, 如果结果超出了{@code int}的范围,则会抛出一个异常.
     *
     * @param a 要自增的值
     * @return 计算结果
     * @throws ArithmeticException 如果结果超出了int的范围
     * @since 1.8
     */
    public static int incrementExact(int a) {
        if (a == Integer.MAX_VALUE) {
            throw new ArithmeticException("integer overflow");
        }

        return a + 1;
    }

    /**
     * 返回参数加一后的结果, 如果结果超出了{@code long}的范围,则会抛出一个异常.
     * result overflows a {@code long}.
     *
     * @param a 要自增的值
     * @return 计算结果
     * @throws ArithmeticException 如果结果超出了long的范围
     * @since 1.8
     */
    public static long incrementExact(long a) {
        if (a == Long.MAX_VALUE) {
            throw new ArithmeticException("long overflow");
        }

        return a + 1L;
    }

    /**
     * 返回参数减一后的结果, 如果结果超出了{@code int}的范围,则会抛出一个异常.
     *
     * @param a 要自减的值
     * @return 计算结果
     * @throws ArithmeticException 如果结果超出了int的范围
     * @since 1.8
     */
    public static int decrementExact(int a) {
        if (a == Integer.MIN_VALUE) {
            throw new ArithmeticException("integer overflow");
        }

        return a - 1;
    }

    /**
     * 返回参数减一后的结果, 如果结果超出了{@code long}的范围,则会抛出一个异常.
     *
     * @param a 要自减的值
     * @return 计算结果
     * @throws ArithmeticException 如果结果超出了long的范围
     * @since 1.8
     */
    public static long decrementExact(long a) {
        if (a == Long.MIN_VALUE) {
            throw new ArithmeticException("long overflow");
        }

        return a - 1L;
    }

    /**
     * 返回参数的相反数, 如果结果溢出{@code int}的范围,则会抛出一个异常.
     *
     * @param a 要取反的值
     * @return 计算结果
     * @throws ArithmeticException 结果溢出{@code int}的范围
     * @since 1.8
     */
    public static int negateExact(int a) {
        if (a == Integer.MIN_VALUE) {
            throw new ArithmeticException("integer overflow");
        }

        return -a;
    }

    /**
     * 返回参数的相反数, 如果结果溢出{@code long}的范围,则会抛出一个
     *
     * @param a 要取反的值
     * @return 计算结果
     * @throws ArithmeticException 结果溢出{@code long}的范围
     * @since 1.8
     */
    public static long negateExact(long a) {
        if (a == Long.MIN_VALUE) {
            throw new ArithmeticException("long overflow");
        }

        return -a;
    }

    /**
     * 返回转换为int类型的{@code long}参数的值;
     * 如果结果溢出{@code int}的范围,则会抛出一个异常.
     *
     * @param value long值
     * @return 转换为int的参数
     * @throws ArithmeticException 如果{@code argument}溢出{@code int}的范围
     * @since 1.8
     */
    public static int toIntExact(long value) {
        if ((int)value != value) {
            throw new ArithmeticException("integer overflow");
        }
        return (int)value;
    }

    /**
     * 返回小于或等于代数商数的最大的(最接近正无穷)的{@code int}值.
     * 有一种特殊情况是, 如果被除数{@linkplain Integer#MIN_VALUE Integer.MIN_VALUE}并且除数是{@code -1},
     * 那么就会出现整数(integer)溢出,那么结果就等于{@code Integer.MIN_VALUE}.
     * <p>
     * 正常的整数(integer)除法操作采用的是取接近0的舍入模式(截断).
     * 除法操作代替了趋向负无穷(底部)的舍入模式(译者注:floorDiv采用的就是趋向负无穷的舍入模式).
     *
     * 当真实的结果为负数时,相比于截断,底部舍入模式(floor rounding mode)会给出不同的结果.
     * <ul>
     *   <li>如果参数的符号相同, 那么{@code floorDiv}和{@code /}运算的结果相同.<br>
     *       例如, {@code floorDiv(4, 3) == 1},{@code (4 / 3) == 1}.</li>
     *   <li>如果参数的符号不同, 那么商数为负数, {@code floorDiv}会返回小于或者等于商数的整数,
     *       而{@code /}运算返回的则是最接近0的整数.<br>
     *       例如, {@code floorDiv(-4, 3) == -2},然而 {@code (-4 / 3) == -1}.
     *
     *   </li>
     * </ul>
     * <p>
     *
     * @param x 被除数
     * @param y 除数
     * @return the largest (最接近正无穷)
     * {@code int} 小于或者等于商数的值.
     * @throws ArithmeticException 如果除数 {@code y}为0
     * @see #floorMod(int, int)
     * @see #floor(double)
     * @since 1.8
     */
    public static int floorDiv(int x, int y) {
        int r = x / y;
        // if the signs are different and modulo not zero, round down
        if ((x ^ y) < 0 && (r * y != x)) {
            r--;
        }
        return r;
    }

    /**
     * 返回小于或等于代数商数的最大的(最接近正无穷)的{@code long}值.
     * 有一种特殊情况是, 如果被除数{@linkplain Long#MIN_VALUE Long.MIN_VALUE}并且除数是{@code -1},
     * 那么就会出现整数(integer)溢出,那么结果就等于{@code Long.MIN_VALUE}.
     * <p>
     * 正常的整数(integer)除法操作采用的是取接近0的舍入模式(截断).
     * 除法操作代替了趋向负无穷(底部)的舍入模式(译者注:floorDiv采用的就是趋向负无穷的舍入模式).
     *
     * 当真实的结果为负数时,相比于截断,底部舍入模式(floor rounding mode)会给出不同的结果.
     * <p>
     * For examples, see {@link #floorDiv(int, int)}.
     *
     * @param x 被除数
     * @param y 除数
     * @return the largest (最接近正无穷)
     * {@code long} 小于或者等于商数的值.
     * @throws ArithmeticException 如果除数 {@code y}为0
     * @see #floorMod(long, long)
     * @see #floor(double)
     * @since 1.8
     */
    public static long floorDiv(long x, long y) {
        long r = x / y;
        // if the signs are different and modulo not zero, round down
        if ((x ^ y) < 0 && (r * y != x)) {
            r--;
        }
        return r;
    }

    /**
     * 返回 {@code int}参数的底模(floor modulus).
     * <p>
     * 底模(floor modulus)是指 {@code x - (floorDiv(x, y) * y)},
     * 符号与除数 {@code y}的相同, 并且在此范围内:{@code -abs(y) < r < +abs(y)}
     *
     * <p>
     * {@code floorDiv} 与 {@code floorMod} 的关系如下:
     * <ul>
     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
     * </ul>
     * <p>
     * {@code floorMod}与{@code %}运算的值不同是因为 {@code floorDiv} 返回的是小于或等于商数的整数而{@code /}运算返回的是最接近0的整数.
     * <p>
     * Examples:
     * <ul>
     *   <li>如果参数的符号相同, 那么 {@code floorMod}和 {@code %}运算的结果相同.<br>
     *       <ul>
     *       <li>{@code floorMod(4, 3) == 1}; &nbsp;  {@code (4 % 3) == 1}</li>
     *       </ul>
     *   <li>如果参数的符号不同, 那么结果和 {@code %}运算结果的不同.<br>
     *      <ul>
     *      <li>{@code floorMod(+4, -3) == -2}; &nbsp;  {@code (+4 % -3) == +1} </li>
     *      <li>{@code floorMod(-4, +3) == +2}; &nbsp;  {@code (-4 % +3) == -1} </li>
     *      <li>{@code floorMod(-4, -3) == -1}; &nbsp;  {@code (-4 % -3) == -1 } </li>
     *      </ul>
     *   </li>
     * </ul>
     * <p>
     * 如果参数的符号是未知的但是却需要一个正的取模结果,那么可以这样计算:{@code (floorMod(x, y) + abs(y)) % abs(y)}.
     *
     * @param x 被除数
     * @param y 除数
     * @return  floor modulus {@code x - (floorDiv(x, y) * y)}
     * @throws ArithmeticException 如果除数 {@code y}为0
     * @see #floorDiv(int, int)
     * @since 1.8
     */
    public static int floorMod(int x, int y) {
        int r = x - floorDiv(x, y) * y;
        return r;
    }

    /**
     * 返回 {@code long}参数的底模(floor modulus).
     * <p>
     * 底模(floor modulus)是指{@code x - (floorDiv(x, y) * y)},
     * 与除数 {@code y}有着相同的符号, 并且在此范围内:{@code -abs(y) < r < +abs(y)}.
     *
     * <p>
     * {@code floorDiv} 与 {@code floorMod} 的关系如下:
     * <ul>
     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
     * </ul>
     * <p>
     * 示例, 参考 {@link #floorMod(int, int)}.
     *
     * @param x 被除数
     * @param y 除数
     * @return floor modulus {@code x - (floorDiv(x, y) * y)}
     * @throws ArithmeticException 如果除数 {@code y}为0
     * @see #floorDiv(long, long)
     * @since 1.8
     */
    public static long floorMod(long x, long y) {
        return x - floorDiv(x, y) * y;
    }

    /**
     * 返回一个{@code int}值的绝对值.
     * 如果参数不是负数, 那么返回该参数.
     * 如果参数是负数,那么返回该参数的相反值.
     *
     * <p>需要注意的是,如果参数等于{@link Integer#MIN_VALUE}的值,即能够表示的最小负{@code int}值,
     * 那么结果与该值相同且为负.
     *
     * @param   a   要确定绝对值的参数
     * @return  参数的绝对值.
     */
    public static int abs(int a) {
        return (a < 0) ? -a : a;
    }

    /**
     * 返回一个{@code long}值的绝对值.
     * 如果参数不是负数, 那么返回该参数.
     * 如果参数是负数,那么返回该参数的相反值.
     *
     * <p>需要注意的是,如果参数等于{@link Long#MIN_VALUE}的值,即能够表示的最小负{@code long}值,
     * 那么结果与该值相同且为负.
     *
     * @param   a   要确定绝对值的参数
     * @return  参数的绝对值.
     */
    public static long abs(long a) {
        return (a < 0) ? -a : a;
    }

    /**
     * 返回一个{@code float}值的绝对值.
     * 如果参数不是负数, 那么返回该参数.
     * 如果参数是负数,那么返回该参数的相反值.
     * 特殊情况如下:
     * <ul><li>如果参数是正0或者负0, 那么结果为正0.
     * <li>如果参数是无穷的, 那么结果为正无穷.
     * <li>如果参数为NaN, 结果为NaN.</ul>
     * 换句话说, 结果和下列表达式的值相同:
     * <p>{@code Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))}
     *
     * @param   a   要确定绝对值的参数
     * @return  参数的绝对值.
     */
    public static float abs(float a) {
        return (a <= 0.0F) ? 0.0F - a : a;
    }

    /**
     * 返回一个{@code double}值的绝对值.
     * 如果参数不是负数, 那么返回该参数.
     * 如果参数是负数,那么返回该参数的相反值.
     * 特殊情况如下:
     * <ul><li>如果参数是正0或者负0, 那么结果为正0.
     * <li>如果参数是无穷的,那么结果为正无穷.
     * <li>如果参数为NaN, 结果为NaN.</ul>
     * 换句话说, 结果和下列表达式的值相同:
     * <p>{@code Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)}
     *
     * @param   a   要确定绝对值的参数
     * @return  参数的绝对值.
     */
    public static double abs(double a) {
        return (a <= 0.0D) ? 0.0D - a : a;
    }

    /**
     * 返回两个{@code int}值中较大的值．
     * 这就是说,结果是更接近{@link Integer#MAX_VALUE}的值.
     * 如果参数有相同的值,那么结果就是该值.
     *
     * @param   a   一个参数.
     * @param   b   另一个参数.
     * @return  {@code a}和{@code b}中较大的值.
     */
    public static int max(int a, int b) {
        return (a >= b) ? a : b;
    }

    /**
     * 返回两个{@code long}值中较大的值．
     * 这就是说,结果是更接近{@link Long#MAX_VALUE}的值.
     * 如果参数有相同的值,那么结果就是该值.
     *
     * @param   a   一个参数.
     * @param   b   另一个参数.
     * @return  {@code a}和{@code b}中较大的值.
     */
    public static long max(long a, long b) {
        return (a >= b) ? a : b;
    }

    // Use raw bit-wise conversions on guaranteed non-NaN arguments.
    private static long negativeZeroFloatBits  = Float.floatToRawIntBits(-0.0f);
    private static long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);

    /**
     *　返回两个{@code float}值中较大的值．
     * 这就是说,结果是更接近正无穷的值.
     * 如果参数有相同的值,那么结果就是该值.
     * 如果其中任意一个为NaN,那么结果为NaN.
     * 与数值比较运算不同,该方法认为负 0 严格小于正 0.
     * 如果一个参数为正0,而另一个参数为负0,那么结果为正0.
     *
     * @param   a   一个参数.
     * @param   b   另一个参数.
     * @return  {@code a}和{@code b}中较大的值.
     */
    public static float max(float a, float b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0f) &&
            (b == 0.0f) &&
            (Float.floatToRawIntBits(a) == negativeZeroFloatBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a >= b) ? a : b;
    }

    /**
     * 返回两个{@code double}值中较大的值．
     * 这就是说,结果是更接近正无穷的值.
     * 如果参数有相同的值,那么结果就是该值.
     * 如果其中任意一个为NaN,那么结果为NaN.
     * 与数值比较运算不同,该方法认为负 0 严格小于正 0.
     * 如果一个参数为正0,而另一个参数为负0,那么结果为正0.
     *
     * @param   a   一个参数.
     * @param   b   另一个参数.
     * @return  {@code a}和{@code b}中较大的值.
     */
    public static double max(double a, double b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0d) &&
            (b == 0.0d) &&
            (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a >= b) ? a : b;
    }

    /**
     * 返回两个{@code int}值中较小的值.
     * 这就是说,结果是更接近{@link Integer#MIN_VALUE}的值.
     * 如果参数有相同的值,那么结果就是该值.
     *
     * @param   a   一个参数.
     * @param   b   另一个参数.
     * @return  {@code a}和{@code b}中较小的值.
     */
    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }

    /**
     * 返回两个{@code long}值中较小的值.
     * 这就是说,结果是更接近{@link Long#MIN_VALUE}的值.
     * 如果参数有相同的值,那么结果就是该值.
     *
     * @param   a   一个参数.
     * @param   b   另一个参数.
     * @return  {@code a}和{@code b}中较小的值.
     */
    public static long min(long a, long b) {
        return (a <= b) ? a : b;
    }

    /**
     * 返回两个{@code float}值中较小的值.
     * 这就是说,结果是更接近负无穷的值.
     * 如果参数有相同的值,那么结果就是该值.
     * 如果其中任意一个为NaN,那么结果为NaN.
     * 与数值比较运算不同,该方法认为负 0 严格小于正 0.
     * 如果一个参数为正0,而另一个参数为负0,那么结果为负0.
     *
     * @param   a   一个参数.
     * @param   b   另一个参数.
     * @return  {@code a}和{@code b}中较小的值.
     */
    public static float min(float a, float b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0f) &&
            (b == 0.0f) &&
            (Float.floatToRawIntBits(b) == negativeZeroFloatBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a <= b) ? a : b;
    }

    /**
     * 返回两个{@code double}值中较小的值.
     * 这就是说,结果是更接近负无穷的值.
     * 如果参数有相同的值,那么结果就是该值.
     * 如果其中任意一个为NaN,那么结果为NaN.
     * 与数值比较运算不同,该方法认为负 0 严格小于正 0.
     * 如果一个参数为正0,而另一个参数为负0,那么结果为负0.
     *
     * @param   a   一个参数.
     * @param   b   另一个参数.
     * @return  {@code a}和{@code b}中较小的值.
     */
    public static double min(double a, double b) {
        if (a != a)
            return a;   // a is NaN
        if ((a == 0.0d) &&
            (b == 0.0d) &&
            (Double.doubleToRawLongBits(b) == negativeZeroDoubleBits)) {
            // Raw conversion ok since NaN can't map to -0.0.
            return b;
        }
        return (a <= b) ? a : b;
    }

    /**
     * 返回参数的 ulp 大小.
     * {@code double} 值的ulp(最后一位的进退位)是该浮点值与下一个数值较大的 {@code double} 值之间的正距离.
     * 需要注意的是, 对于非NaN的<i>x</i>, <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
     *
     * <p>特殊情况如下:
     * <ul>
     * <li> 如果参数为NaN, 那么结果为NaN.
     * <li> 如果参数是正无穷或者负无穷, 那么返回结果为正无穷.
     * <li> 如果参数是正0或者负0, 那么返回结果为{@code Double.MIN_VALUE}.
     * <li> 如果参数是 &plusmn;{@code Double.MAX_VALUE}, 那么返回结果等于 2<sup>971</sup>.
     * </ul>
     *
     * @param d 要返回 ulp 的浮点值
     * @return 返回参数的 ulp 大小.
     * @author Joseph D. Darcy
     * @since 1.5
     */
    public static double ulp(double d) {
        int exp = getExponent(d);

        switch(exp) {
        case DoubleConsts.MAX_EXPONENT+1:       // NaN or infinity
            return Math.abs(d);

        case DoubleConsts.MIN_EXPONENT-1:       // zero or subnormal
            return Double.MIN_VALUE;

        default:
            assert exp <= DoubleConsts.MAX_EXPONENT && exp >= DoubleConsts.MIN_EXPONENT;

            // ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
            exp = exp - (DoubleConsts.SIGNIFICAND_WIDTH-1);
            if (exp >= DoubleConsts.MIN_EXPONENT) {
                return powerOfTwoD(exp);
            }
            else {
                // return a subnormal result; left shift integer
                // representation of Double.MIN_VALUE appropriate
                // number of positions
                return Double.longBitsToDouble(1L <<
                (exp - (DoubleConsts.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1)) ));
            }
        }
    }

    /**
     * 返回参数的 ulp 大小.
     * {@code float} 值的ulp(最后一位的进退位)是该浮点值与下一个数值较大的 {@code float} 值之间的正距离.
     * 需要注意的是, 对于非NaN的<i>x</i>, <code>ulp(-<i>x</i>) == ulp(<i>x</i>)</code>.
     *
     * <p>特殊情况如下:
     * <ul>
     * <li> 如果参数为NaN, 那么结果为NaN.
     * <li> 如果参数是正无穷或者负无穷, 那么返回结果为正无穷.
     * <li> 如果参数是正0或者负0, 那么返回结果为{@code Float.MIN_VALUE}.
     * <li> 如果参数是 &plusmn;{@code Float.MAX_VALUE}, 那么结果等于 2<sup>104</sup>.
     * </ul>
     *
     * @param f 要返回 ulp 的浮点值
     * @return 参数的 ulp 大小
     * @author Joseph D. Darcy
     * @since 1.5
     */
    public static float ulp(float f) {
        int exp = getExponent(f);

        switch(exp) {
        case FloatConsts.MAX_EXPONENT+1:        // NaN or infinity
            return Math.abs(f);

        case FloatConsts.MIN_EXPONENT-1:        // zero or subnormal
            return FloatConsts.MIN_VALUE;

        default:
            assert exp <= FloatConsts.MAX_EXPONENT && exp >= FloatConsts.MIN_EXPONENT;

            // ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
            exp = exp - (FloatConsts.SIGNIFICAND_WIDTH-1);
            if (exp >= FloatConsts.MIN_EXPONENT) {
                return powerOfTwoF(exp);
            }
            else {
                // return a subnormal result; left shift integer
                // representation of FloatConsts.MIN_VALUE appropriate
                // number of positions
                return Float.intBitsToFloat(1 <<
                (exp - (FloatConsts.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1)) ));
            }
        }
    }

    /**
     * 返回参数的符号函数;
     * 如果参数为 0, 则返回 0;
     * 如果参数大于 0, 则返回 1.0;
     * 如果参数小于 0, 则返回 -1.0.
     *
     * <p>特殊情况如下:
     * <ul>
     * <li> 如果参数为NaN, 那么结果为NaN.
     * <li> 如果参数是正0或者负0, 那么结果和参数有相同的符号.
     * </ul>
     *
     * @param d 要返回符号函数的浮点值
     * @return 参数的符号函数
     * @author Joseph D. Darcy
     * @since 1.5
     */
    public static double signum(double d) {
        return (d == 0.0 || Double.isNaN(d))?d:copySign(1.0, d);
    }

    /**
     * 返回参数的符号函数;
     * 如果参数为 0, 则返回 0;
     * 如果参数大于 0, 则返回 1.0f;
     * 如果参数小于 0, 则返回 -1.0f.
     *
     * <p>特殊情况如下:
     * <ul>
     * <li> 如果参数为NaN, 那么结果为NaN.
     * <li> 如果参数是正0或者负0, 那么结果和参数有相同的符号.
     * </ul>
     *
     * @param f 要返回符号函数的浮点值
     * @return 参数的符号函数
     * @author Joseph D. Darcy
     * @since 1.5
     */
    public static float signum(float f) {
        return (f == 0.0f || Float.isNaN(f))?f:copySign(1.0f, f);
    }

    /**
     * 返回一个 {@code double} 值的双曲正弦.
     * <i>x</i>的双曲线正弦的定义是 (<i>e<sup>x</sup>&nbsp;-&nbsp;e<sup>-x</sup></i>)/2,
     * 其中<i>e</i>是{@linkplain Math#E 欧拉数}.
     *
     * <p>特殊情况如下:
     * <ul>
     *
     * <li>如果参数为NaN, 那么结果为NaN.
     *
     * <li>如果参数是无穷大, 那么结果为无穷大, 符号和参数的符号相同..
     *
     * <li>如果参数为0, 那么结果为0, 符号和参数的符号相同.
     *
     * </ul>
     *
     * <p>计算结果必须在准确结果的 2.5 ulp 范围内.
     *
     * @param   x 要返回其双曲线正弦的数字.
     * @return  {@code x}的双曲线正弦.
     * @since 1.5
     */
    public static double sinh(double x) {
        return StrictMath.sinh(x);
    }

    /**
     * 返回一个 {@code double} 值的双曲余弦.
     * <i>x</i>的双曲线余弦的定义是(<i>e<sup>x</sup>&nbsp;+&nbsp;e<sup>-x</sup></i>)/2,
     * 其中<i>e</i>是{@linkplain Math#E 欧拉数}.
     *
     * <p>特殊情况如下:
     * <ul>
     *
     * <li>如果参数为NaN, 那么结果为NaN.
     *
     * <li>如果参数是无穷的, 那么结果为正无穷.
     *
     * <li>如果参数为0, 那么结果为{@code 1.0}.
     *
     * </ul>
     *
     * <p>计算结果必须在准确结果的 2.5 ulp 范围内.
     *
     * @param   x 要返回其双曲线余弦的数字.
     * @return  {@code x}的双曲线余弦.
     * @since 1.5
     */
    public static double cosh(double x) {
        return StrictMath.cosh(x);
    }

    /**
     * 返回一个 {@code double} 值的双曲线正切.
     * <i>x</i>的双曲线正切的定义是(<i>e<sup>x</sup>&nbsp;-&nbsp;e<sup>-x</sup></i>)/(<i>e<sup>x</sup>&nbsp;+&nbsp;e<sup>-x</sup></i>),
     * 即, {@linkplain Math#sinh sinh(<i>x</i>)}/{@linkplain Math#cosh cosh(<i>x</i>)}.
     * 需要注意的是,准确的 tanh 绝对值始终小于 1.
     *
     * <p>特殊情况如下:
     * <ul>
     *
     * <li>如果参数为NaN, 那么结果为NaN.
     *
     * <li>如果参数为0, 那么结果为0, 符号和参数的符号相同.
     *
     * <li>如果参数为正无穷, 那么结果为{@code +1.0}.
     *
     * <li>如果参数为负无穷, 那么结果为{@code -1.0}.
     *
     * </ul>
     *
     * <p>计算结果必须在准确结果的 2.5 ulp 范围内.
     * 任何有限输入值的 {@code tanh} 结果的绝对值必定小于或等于 1.
     * 需要注意的是, 一旦准确的 {@code tanh} 结果在极限值 &plusmn;1 的 1/2 ulp 内,
     * 那么应该返回有正确符号的 &plusmn;{@code 1.0}
     *
     * @param   x 要返回其双曲线正切的数字.
     * @return  {@code x}的双曲线正切.
     * @since 1.5
     */
    public static double tanh(double x) {
        return StrictMath.tanh(x);
    }

    /**
     * 返回没有中间溢出或下溢的sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>).
     *
     * <p>特殊情况如下:
     * <ul>
     * <li> 如果任意一个参数是无穷大, 那么返回结果为正无穷.
     * <li> 如果任意一个参数为NaN, 并且两个参数都不是无穷大, 那么结果为NaN.
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 如果一个参数保持常量, 那么在另一个参数中, 结果必须具有半单调性.
     *
     * @param x　一个值
     * @param y　一个值
     * @return 没有中间溢出或下溢的sqrt(<i>x</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
     * @since 1.5
     */
    public static double hypot(double x, double y) {
        return StrictMath.hypot(x, y);
    }

    /**
     * 返回<i>e</i><sup>x</sup>&nbsp;-1.
     * 需要注意的是,对于接近 0 的 <i>x</i>值,
     * {@code expm1(x)}&nbsp;+&nbsp;1 比 {@code exp(x)} 更接近<i>e</i><sup>x</sup>的真实结果.
     *
     * <p>特殊情况如下:
     * <ul>
     * <li>如果参数为NaN, 结果为NaN.
     *
     * <li>如果参数为正无穷, 那么结果为正无穷.
     *
     * <li>如果参数为负无穷, 那么结果为 -1.0.
     *
     * <li>如果参数为0,那么结果为0,符号和参数的符号相同.
     *
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性. 对于任何有限输入值, {@code expm1}的结果必须大于或者等于{@code -1.0}.
     * 需要注意的是,一旦<i>e</i><sup>{@code x}</sup>&nbsp;-&nbsp;1的准确结果在极限值-1的 1/2 ulp范围内,
     * 那么应当返回{@code -1.0}.
     *
     * @param   x   在<i>e</i><sup>{@code x}</sup>&nbsp;-1的计算中<i>e</i>的指数.
     * @return <i>e</i><sup>{@code x}</sup>&nbsp;-&nbsp;1的值.
     * @since 1.5
     */
    public static double expm1(double x) {
        return StrictMath.expm1(x);
    }

    /**
     * 返回参数与1之和的自然对数.
     * 需要注意的是,对于小于{@code x}的值,{@code log1p(x)} 的结果
     * 比 {@code log(1.0+x)} 的浮点计算结果更接近  ln(1 + {@code x}) 的实际结果.
     *
     * <p>特殊情况如下:
     *
     * <ul>
     *
     * <li>如果参数为NaN或者小于 -1, 那么结果为NaN.
     *
     * <li>如果参数为正无穷, 那么结果为正无穷.
     *
     * <li>I如果参数为负数, 那么结果为负无穷.
     *
     * <li>如果参数为0, 那么结果为0, 符号同参数相同.
     *
     * </ul>
     *
     * <p>计算结果必须在准确结果的 1 ulp 范围内.
     * 结果必须具有半单调性.
     *
     * @param   x  一个值
     * @return ln({@code x}&nbsp;+&nbsp;1)的值,即 {@code x}&nbsp;+&nbsp;1 的自然对数
     * @since 1.5
     */
    public static double log1p(double x) {
        return StrictMath.log1p(x);
    }

    /**
     * 返回符号为第二个浮点参数符号的第一个浮点参数.
     * 需要注意的是, 不像{@link StrictMath#copySign(double, double) StrictMath.copySign}方法,
     * 该方法不要求将NaN {@code sign}当作正值;
     * 允许实现将某些 NaN 参数当作正, 将另一些当作负, 以获得更好的性能.
     *
     * @param magnitude  提供结果数值的参数
     * @param sign   提供结果符号的参数
     * @return 一个符号为{@code sign}且数值为{@code magnitude}的值.
     * @since 1.6
     */
    public static double copySign(double magnitude, double sign) {
        return Double.longBitsToDouble((Double.doubleToRawLongBits(sign) &
                                        (DoubleConsts.SIGN_BIT_MASK)) |
                                       (Double.doubleToRawLongBits(magnitude) &
                                        (DoubleConsts.EXP_BIT_MASK |
                                         DoubleConsts.SIGNIF_BIT_MASK)));
    }

    /**
     * 返回符号为第二个浮点参数符号的第一个浮点参数.
     * 需要注意的是, 不像{@link StrictMath#copySign(float, float) StrictMath.copySign}方法,
     * 该方法不要求将NaN {@code sign}当作正值;
     * 允许实现将某些 NaN 参数当作正, 将另一些当作负, 以获得更好的性能.
     *
     * @param magnitude  提供结果数值的参数
     * @param sign   提供结果符号的参数
     * @return 一个符号为{@code sign}且数值为{@code magnitude}的值.
     * @since 1.6
     */
    public static float copySign(float magnitude, float sign) {
        return Float.intBitsToFloat((Float.floatToRawIntBits(sign) &
                                     (FloatConsts.SIGN_BIT_MASK)) |
                                    (Float.floatToRawIntBits(magnitude) &
                                     (FloatConsts.EXP_BIT_MASK |
                                      FloatConsts.SIGNIF_BIT_MASK)));
    }

    /**
     * 返回{@code float}表示形式中使用的无偏指数.
     * 特殊情况如下:
     *
     * <ul>
     * <li>如果参数为NaN或者无穷大,那么返回结果为{@link Float#MAX_EXPONENT} + 1.
     * <li>如果参数为0或非规格化浮点数, 那么返回结果为{@link Float#MIN_EXPONENT} - 1.
     * </ul>
     * @param f 一个{@code float}值
     * @return 参数的无偏指数
     * @since 1.6
     */
    public static int getExponent(float f) {
        /*
         * Bitwise convert f to integer, mask out exponent bits, shift
         * to the right and then subtract out float's bias adjust to
         * get true exponent value
         */
        return ((Float.floatToRawIntBits(f) & FloatConsts.EXP_BIT_MASK) >>
                (FloatConsts.SIGNIFICAND_WIDTH - 1)) - FloatConsts.EXP_BIAS;
    }

    /**
     * 返回{@code double}表示形式中使用的无偏指数.
     * 特殊情况如下:
     *
     * <ul>
     * <li>如果参数为NaN或者无穷大,那么结果为{@link Double#MAX_EXPONENT} + 1.
     *
     * <li>如果参数为0或非规格化浮点数, 那么结果为{@link Double#MIN_EXPONENT} -1.
     * </ul>
     * @param d 一个{@code double}值
     * @return 参数的无偏指数
     * @since 1.6
     */
    public static int getExponent(double d) {
        /*
         * Bitwise convert d to long, mask out exponent bits, shift
         * to the right and then subtract out double's bias adjust to
         * get true exponent value.
         */
        return (int)(((Double.doubleToRawLongBits(d) & DoubleConsts.EXP_BIT_MASK) >>
                      (DoubleConsts.SIGNIFICAND_WIDTH - 1)) - DoubleConsts.EXP_BIAS);
    }

    /**
     * 返回第一个参数和第二个参数之间与第一个参数相邻的浮点数.
     * 如果两个参数比较起来相等, 则返回一个与第二个参数相等的值.
     *
     * <p>
     * 特殊情况如下:
     * <ul>
     * <li> 如果任意一个参数为NaN,那么返回NaN.
     *
     * <li> 如果两个参数都是有符号的0,那么则不做更改地返回{@code direction}(根据要求, 如果参数比较起来相等, 将返回第二个参数).
     *
     * <li> 如果{@code start}为&plusmn;{@link Double#MIN_VALUE},
     * 并且{@code direction}的值要求结果为一个比{@code start}小的数值,
     * 那么返回0,符号和{@code start}相同.
     *
     * <li> 如果{@code start}为无穷大,
     * 并且{@code direction}的值要求结果为一个比{@code start}小的数值,
     * 那么返回{@link Double#MAX_VALUE},符号和{@code start}相同.
     *
     * <li>如果{@code start}等于 &plusmn;　{@link Double#MAX_VALUE},
     * 并且{@code direction}的值要求结果为一个比{@code start}大的数值,
     * 那么返回无穷大, 并带有与{@code start}相同的符号.
     * </ul>
     *
     * @param start  起始浮点值.
     * @param direction  一个值,指明指示应返回 {@code start} 的某个邻数还是 {@code start}
     * @return {@code start} 和 {@code direction} 之间与 {@code start} 相邻的浮点数.
     * @since 1.6
     */
    public static double nextAfter(double start, double direction) {
        /*
         * The cases:
         *
         * nextAfter(+infinity, 0)  == MAX_VALUE
         * nextAfter(+infinity, +infinity)  == +infinity
         * nextAfter(-infinity, 0)  == -MAX_VALUE
         * nextAfter(-infinity, -infinity)  == -infinity
         *
         * are naturally handled without any additional testing
         */

        // First check for NaN values
        if (Double.isNaN(start) || Double.isNaN(direction)) {
            // return a NaN derived from the input NaN(s)
            return start + direction;
        } else if (start == direction) {
            return direction;
        } else {        // start > direction or start < direction
            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
            // then bitwise convert start to integer.
            long transducer = Double.doubleToRawLongBits(start + 0.0d);

            /*
             * IEEE 754 floating-point numbers are lexicographically
             * ordered if treated as signed- magnitude integers .
             * Since Java's integers are two's complement,
             * incrementing" the two's complement representation of a
             * logically negative floating-point value *decrements*
             * the signed-magnitude representation. Therefore, when
             * the integer representation of a floating-point values
             * is less than zero, the adjustment to the representation
             * is in the opposite direction than would be expected at
             * first .
             */
            if (direction > start) { // Calculate next greater value
                transducer = transducer + (transducer >= 0L ? 1L:-1L);
            } else  { // Calculate next lesser value
                assert direction < start;
                if (transducer > 0L)
                    --transducer;
                else
                    if (transducer < 0L )
                        ++transducer;
                    /*
                     * transducer==0, the result is -MIN_VALUE
                     *
                     * The transition from zero (implicitly
                     * positive) to the smallest negative
                     * signed magnitude value must be done
                     * explicitly.
                     */
                    else
                        transducer = DoubleConsts.SIGN_BIT_MASK | 1L;
            }

            return Double.longBitsToDouble(transducer);
        }
    }

    /**
     * 返回第一个参数和第二个参数之间与第一个参数相邻的浮点数.
     * 如果两个参数比较起来相等, 则返回一个与第二个参数相等的值.
     *
     * <p>
     * 特殊情况如下:
     * <ul>
     * <li> 如果任意一个参数为NaN,那么返回NaN.
     * <li> 如果两个参数都是有符号的0,那么返回结果等于{@code direction}.
     * <li> 如果{@code start}为&plusmn;{@link Float#MIN_VALUE},
     * 而{@code direction}的值要求结果为一个比{@code start}小的数值,
     * 那么将返回0, 符号和{@code start}相同.
     * <li> 如果{@code start}是无穷大的,并且{@code direction}的值要求结果为一个比{@code start}小的数值,
     * 那么返回{@link Float#MAX_VALUE},符号和{@code start}相同.
     * <li>如果{@code start}等于 &plusmn;{@link Float#MAX_VALUE},
     * 并且{@code direction}的值要求结果为一个比{@code start}大的数值,那么返回无穷大,符号和{@code start}相同.
     * </ul>
     *
     * @param start  起始浮点值
     * @param direction  一个值,指明应返回{@code start}的某个邻数还是{@code start}
     * @return {@code direction}之间与{@code start}相邻的浮点数.
     * @since 1.6
     */
    public static float nextAfter(float start, double direction) {
        /*
         * The cases:
         *
         * nextAfter(+infinity, 0)  == MAX_VALUE
         * nextAfter(+infinity, +infinity)  == +infinity
         * nextAfter(-infinity, 0)  == -MAX_VALUE
         * nextAfter(-infinity, -infinity)  == -infinity
         *
         * are naturally handled without any additional testing
         */

        // First check for NaN values
        if (Float.isNaN(start) || Double.isNaN(direction)) {
            // return a NaN derived from the input NaN(s)
            return start + (float)direction;
        } else if (start == direction) {
            return (float)direction;
        } else {        // start > direction or start < direction
            // Add +0.0 to get rid of a -0.0 (+0.0 + -0.0 => +0.0)
            // then bitwise convert start to integer.
            int transducer = Float.floatToRawIntBits(start + 0.0f);

            /*
             * IEEE 754 floating-point numbers are lexicographically
             * ordered if treated as signed- magnitude integers .
             * Since Java's integers are two's complement,
             * incrementing" the two's complement representation of a
             * logically negative floating-point value *decrements*
             * the signed-magnitude representation. Therefore, when
             * the integer representation of a floating-point values
             * is less than zero, the adjustment to the representation
             * is in the opposite direction than would be expected at
             * first.
             */
            if (direction > start) {// Calculate next greater value
                transducer = transducer + (transducer >= 0 ? 1:-1);
            } else  { // Calculate next lesser value
                assert direction < start;
                if (transducer > 0)
                    --transducer;
                else
                    if (transducer < 0 )
                        ++transducer;
                    /*
                     * transducer==0, the result is -MIN_VALUE
                     *
                     * The transition from zero (implicitly
                     * positive) to the smallest negative
                     * signed magnitude value must be done
                     * explicitly.
                     */
                    else
                        transducer = FloatConsts.SIGN_BIT_MASK | 1;
            }

            return Float.intBitsToFloat(transducer);
        }
    }

    /**
     * 返回{@code d}和正无穷大之间与{@code d}相邻的浮点值.
     * 该方法在语义上等于{@code nextAfter(d,Double.POSITIVE_INFINITY)};
     * 然而,{@code nextUp}实现的运行速度可能比其等价{@code nextAfter}调用快.
     *
     * <p>特殊情况如下:
     * <ul>
     * <li> 如果参数为NaN, 结果为NaN.
     * <li> 如果参数为正无穷, 那么结果为正无穷.
     * <li> 如果参数为0, 那么结果为{@link Double#MIN_VALUE}.
     * </ul>
     *
     * @param d 起始浮点值．
     * @return 更接近正无穷的相邻浮点数.
     * @since 1.6
     */
    public static double nextUp(double d) {
        if( Double.isNaN(d) || d == Double.POSITIVE_INFINITY)
            return d;
        else {
            d += 0.0d;
            return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
                                           ((d >= 0.0d)?+1L:-1L));
        }
    }

    /**
     * 返回{@code f}和正无穷大之间与{@code f}相邻的浮点值.
     * 该方法在语义上等于{@code nextAfter(f,Float.POSITIVE_INFINITY)};
     * 然而,{@code nextUp}实现的运行速度可能比其等价{@code nextAfter}调用快.
     *
     * <p>特殊情况如下:
     * <ul>
     * <li> 如果参数为NaN, 结果为NaN.
     * <li> 如果参数为正无穷, 那么结果为正无穷.
     * <li> 如果参数为0, 那么结果为{@link Float#MIN_VALUE}.
     * </ul>
     *
     * @param f 起始浮点值．
     * @return 更接近正无穷的相邻浮点数.
     * @since 1.6
     */
    public static float nextUp(float f) {
        if( Float.isNaN(f) || f == FloatConsts.POSITIVE_INFINITY)
            return f;
        else {
            f += 0.0f;
            return Float.intBitsToFloat(Float.floatToRawIntBits(f) +
                                        ((f >= 0.0f)?+1:-1));
        }
    }

    /**
     * 返回{@code d}和负无穷大之间与{@code d}相邻的浮点值.
     * 该方法在语义上等于{@code nextAfter(d,Double.NEGATIVE_INFINITY)};
     * 然而,{@code nextDown}实现的运行速度可能比其等价{@code nextAfter}调用快.
     *
     * <p>特殊情况如下:
     * <ul>
     * <li> 如果参数为NaN, 那么结果为NaN.
     * <li> 如果参数为负无穷, 那么结果为负无穷．
     * <li> 如果参数为0,　那么结果为{@code -Double.MIN_VALUE}
     * </ul>
     *
     * @param d  起始浮点值．
     * @return 更接近负无穷的相邻浮点数.
     * @since 1.8
     */
    public static double nextDown(double d) {
        if (Double.isNaN(d) || d == Double.NEGATIVE_INFINITY)
            return d;
        else {
            if (d == 0.0)
                return -Double.MIN_VALUE;
            else
                return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
                                               ((d > 0.0d)?-1L:+1L));
        }
    }

    /**
     * 返回{@code f}和负无穷大之间与{@code f}相邻的浮点值.
     * 该方法在语义上等于{@code nextAfter(f,Float.NEGATIVE_INFINITY)};
     * 然而,{@code nextDown}实现的运行速度可能比其等价{@code nextAfter}调用快.
     *
     * <p>特殊情况如下:
     * <ul>
     * <li> 如果参数为NaN, 结果为NaN.
     * <li> 如果参数为负无穷, 那么结果为负无穷.
     * <li> 如果参数为0, 那么结果为{@code -Float.MIN_VALUE}
     * </ul>
     *
     * @param f  起始浮点值.
     * @return 更接近负无穷的相邻浮点数.
     * @since 1.8
     */
    public static float nextDown(float f) {
        if (Float.isNaN(f) || f == Float.NEGATIVE_INFINITY)
            return f;
        else {
            if (f == 0.0f)
                return -Float.MIN_VALUE;
            else
                return Float.intBitsToFloat(Float.floatToRawIntBits(f) +
                                            ((f > 0.0f)?-1:+1));
        }
    }

    /**
     * 返回 {@code d} &times; 2<sup>{@code scaleFactor}</sup>,
     * 其舍入方式如同将一个正确舍入的浮点值乘以double值集合中的一个值.
     * 有关浮点值集合的讨论, 请参阅 Java 语言规范.
     * 如果结果的指数在 {@link Double#MIN_EXPONENT} 和 {@link Double#MAX_EXPONENT}之间,则可以正确地计算结果;
     * 如果结果的指数大于{@code Double.MAX_EXPONENT},则返回无穷大.
     * 需要注意的是,如果结果为非规格化浮点数(译者注:原文为subnormal,译者认为应该指的是subnormal number,即非规格化浮点数),
     * 则可能丢失精度;
     * 也就是说,{@code scalb(x, n)}为 subnormal 时,{@code scalb(scalb(x, n), -n)}可能不等于<i>x</i>.
     * 结果为非NaN时, 结果的符号将与{@code d}相同.
     *
     * <p>特殊情况如下:
     * <ul>
     * <li> 如果第一个参数为NaN, 那么返回NaN.
     * <li> 如果第一个参数是无穷大的, 那么返回同样符号的无穷大.
     * <li> 如果第一个参数是0, 那么返回同样符号的0.
     * </ul>
     *
     * @param d 要使用2的次幂去缩放的数.
     * @param scaleFactor 用来缩放{@code d}的2的次幂.
     * @return {@code d} &times; 2<sup>{@code scaleFactor}</sup>
     * @since 1.6
     */
    public static double scalb(double d, int scaleFactor) {
        /*
         * This method does not need to be declared strictfp to
         * compute the same correct result on all platforms.  When
         * scaling up, it does not matter what order the
         * multiply-store operations are done; the result will be
         * finite or overflow regardless of the operation ordering.
         * However, to get the correct result when scaling down, a
         * particular ordering must be used.
         *
         * When scaling down, the multiply-store operations are
         * sequenced so that it is not possible for two consecutive
         * multiply-stores to return subnormal results.  If one
         * multiply-store result is subnormal, the next multiply will
         * round it away to zero.  This is done by first multiplying
         * by 2 ^ (scaleFactor % n) and then multiplying several
         * times by by 2^n as needed where n is the exponent of number
         * that is a covenient power of two.  In this way, at most one
         * real rounding error occurs.  If the double value set is
         * being used exclusively, the rounding will occur on a
         * multiply.  If the double-extended-exponent value set is
         * being used, the products will (perhaps) be exact but the
         * stores to d are guaranteed to round to the double value
         * set.
         *
         * It is _not_ a valid implementation to first multiply d by
         * 2^MIN_EXPONENT and then by 2 ^ (scaleFactor %
         * MIN_EXPONENT) since even in a strictfp program double
         * rounding on underflow could occur; e.g. if the scaleFactor
         * argument was (MIN_EXPONENT - n) and the exponent of d was a
         * little less than -(MIN_EXPONENT - n), meaning the final
         * result would be subnormal.
         *
         * Since exact reproducibility of this method can be achieved
         * without any undue performance burden, there is no
         * compelling reason to allow double rounding on underflow in
         * scalb.
         */

        // magnitude of a power of two so large that scaling a finite
        // nonzero value by it would be guaranteed to over or
        // underflow; due to rounding, scaling down takes takes an
        // additional power of two which is reflected here
        final int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT +
                              DoubleConsts.SIGNIFICAND_WIDTH + 1;
        int exp_adjust = 0;
        int scale_increment = 0;
        double exp_delta = Double.NaN;

        // Make sure scaling factor is in a reasonable range

        if(scaleFactor < 0) {
            scaleFactor = Math.max(scaleFactor, -MAX_SCALE);
            scale_increment = -512;
            exp_delta = twoToTheDoubleScaleDown;
        }
        else {
            scaleFactor = Math.min(scaleFactor, MAX_SCALE);
            scale_increment = 512;
            exp_delta = twoToTheDoubleScaleUp;
        }

        // Calculate (scaleFactor % +/-512), 512 = 2^9, using
        // technique from "Hacker's Delight" section 10-2.
        int t = (scaleFactor >> 9-1) >>> 32 - 9;
        exp_adjust = ((scaleFactor + t) & (512 -1)) - t;

        d *= powerOfTwoD(exp_adjust);
        scaleFactor -= exp_adjust;

        while(scaleFactor != 0) {
            d *= exp_delta;
            scaleFactor -= scale_increment;
        }
        return d;
    }

    /**
     * 返回 {@code f} &times; 2<sup>{@code scaleFactor}</sup>,
     * 其舍入方式如同将一个正确舍入的浮点值乘以float值集合中的一个值.
     * 有关浮点值集合的讨论, 请参阅 Java 语言规范.
     * 如果结果的指数在 {@link Float#MIN_EXPONENT} 和 {@link Float#MAX_EXPONENT}之间,则可以正确地计算结果;
     * 如果结果的指数大于{@code Float.MAX_EXPONENT},则返回无穷大.
     * 需要注意的是,如果结果为非规格化浮点数(译者注:原文为subnormal,译者认为应该指的是subnormal number,即非规格化浮点数),
     * 则可能丢失精度;
     * 也就是说,{@code scalb(x, n)}为 subnormal 时,{@code scalb(scalb(x, n), -n)}可能不等于<i>x</i>.
     * 结果为非NaN时, 结果的符号将与{@code f}相同.
     *
     * <p>特殊情况如下:
     * <ul>
     * <li> 如果第一个参数为NaN, 那么返回NaN.
     * <li> 如果第一个参数为无穷大, 那么返回同样符号的无穷大.
     * <li> 如果第一个参数是0, 那么返回同样符号的0.
     * </ul>
     *
     * @param f 要使用2的次幂去缩放的数.
     * @param scaleFactor 用来缩放{@code f}的2的次幂.
     * @return {@code f} &times; 2<sup>{@code scaleFactor}</sup>
     * @since 1.6
     */
    public static float scalb(float f, int scaleFactor) {
        // magnitude of a power of two so large that scaling a finite
        // nonzero value by it would be guaranteed to over or
        // underflow; due to rounding, scaling down takes takes an
        // additional power of two which is reflected here
        final int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT +
                              FloatConsts.SIGNIFICAND_WIDTH + 1;

        // Make sure scaling factor is in a reasonable range
        scaleFactor = Math.max(Math.min(scaleFactor, MAX_SCALE), -MAX_SCALE);

        /*
         * Since + MAX_SCALE for float fits well within the double
         * exponent range and + float -> double conversion is exact
         * the multiplication below will be exact. Therefore, the
         * rounding that occurs when the double product is cast to
         * float will be the correctly rounded float result.  Since
         * all operations other than the final multiply will be exact,
         * it is not necessary to declare this method strictfp.
         */
        return (float)((double)f*powerOfTwoD(scaleFactor));
    }

    // Constants used in scalb
    static double twoToTheDoubleScaleUp = powerOfTwoD(512);
    static double twoToTheDoubleScaleDown = powerOfTwoD(-512);

    /**
     * 返回一个正常范围内的浮点数的平方.
     */
    static double powerOfTwoD(int n) {
        assert(n >= DoubleConsts.MIN_EXPONENT && n <= DoubleConsts.MAX_EXPONENT);
        return Double.longBitsToDouble((((long)n + (long)DoubleConsts.EXP_BIAS) <<
                                        (DoubleConsts.SIGNIFICAND_WIDTH-1))
                                       & DoubleConsts.EXP_BIT_MASK);
    }

    /**
     * 返回一个正常范围内的浮点数的平方.
     */
    static float powerOfTwoF(int n) {
        assert(n >= FloatConsts.MIN_EXPONENT && n <= FloatConsts.MAX_EXPONENT);
        return Float.intBitsToFloat(((n + FloatConsts.EXP_BIAS) <<
                                     (FloatConsts.SIGNIFICAND_WIDTH-1))
                                    & FloatConsts.EXP_BIT_MASK);
    }
}
